/**
 * 
 */
package info.niwota.webshot;

import java.util.ArrayList;

import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.provider.Browser;
import android.util.Log;

/**
 * @author qiangli
 * 
 */
public final class Bookmarks {
	public static final String SCHEME = "bookmark";
	
	public static class ItemInfo {
		public long date;
		public Object icon;
		public String id;
		public int index; // zero based folder index
		public Intent intent;
		public String sortkey;
		public String title;
		public String url;

		@Override
		public String toString() {
			return id + ":" + title;
		}
	}

	private static final String[] BOOKMARK_PROJ = new String[] {
			Browser.BookmarkColumns._ID, Browser.BookmarkColumns.URL,
			Browser.BookmarkColumns.TITLE, Browser.BookmarkColumns.BOOKMARK,
			Browser.BookmarkColumns.VISITS, Browser.BookmarkColumns.DATE,
			Browser.BookmarkColumns.CREATED,
			Browser.BookmarkColumns.FAVICON, };

	private static final String[] LIST = { "/all", "/favorite", "/most",
			"/recent", };
	
	//private static final String[] TITLES = { "All", "Favorite", "Most",
	//	"Recent", };

	private static final int LIST_ALL = 0; // history sort by title

	private static final int LIST_FAVES = 1;

	private static final int LIST_MOST = 2;

	private static final int LIST_RECENT = 3; // part of history sort by date

	//private static final int MAX_COUNT = 500;

	private static final int MAX_TEXT_LEN = 80;

	private static final String TAG = "Bookmarks";

	public static void add(Context ctx, String title, String url) {
		Browser.saveBookmark(ctx, title, url);
	}

	private static String format(final ItemInfo[] items, final String title,  final String path, final int offset, final int max, boolean page) {
		final StringBuilder sb = new StringBuilder();
		if (page) {
			sb.append("<html><head><title>");
			sb.append(title);
			sb.append("</title>");
			sb.append("<base href=\"");
			final String base = path +"?offset="+ (offset)+"&max=" + max;
			sb.append(base);
			sb.append("\" />");
			sb.append("</head>");
			sb.append("<body>");
		}
		//
		try {
			if (items != null && items.length > 0) {
				//
				sb.append("<ul>");
				//item list
				final int len = items.length;
				final boolean more = (len > max);
				final int cnt = Math.min(max, len);
				for (int i = 0; i < cnt; i++) {
					ItemInfo item = items[i];
					appendItem(sb, item.title, item.url);
				}
				//
				sb.append("<br />");
				//pagination
				final String tab = "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;";
				final int pgsize = (max);
				final int pgcnt = (offset / pgsize) + (offset % pgsize > 0 ? 1 : 0);
				for (int i = 0; i < pgcnt; i++) {
					final String ti = "&nbsp;"+ (i + 1) +"&nbsp;";
					final String li = path +"?offset="+ (pgsize * i)+"&max=" + max;
					appendLink(sb, ti, li);
					sb.append(tab);
					if (Debug.DEBUG) {
						Log.d(TAG, ti + " " + li);
					}
				}
				sb.append("&nbsp;"+ (pgcnt + 1) +"&nbsp;");
				sb.append(tab);
				//
				if (more) {
					final String li = path +"?offset="+ (offset+max)+"&max=" + max;
					appendLink(sb, "More...", li);
					if (Debug.DEBUG) {
						Log.d(TAG, "More... " + li);
					}
				}
				sb.append("</ul>");
			} else {
				sb.append("No bookmark");
			}
		} catch (Exception e) {
			sb.append(e.toString());
		}
		//
		if (page) {
			sb.append("</body></html>");
		}
		return sb.toString();
	}

	private static void appendLink(StringBuilder sb, String title, String url) {
		sb.append("<a class=\"bookmarks\" href=\"");
		sb.append(url);
		sb.append("\">");
		sb.append(title);
		sb.append("</a>");
	}
	
	private static void appendItem(StringBuilder sb, String title, String url) {
		sb.append("<li><a class=\"bookmark\" href=\"");
		sb.append(url);
		sb.append("\">");
		sb.append(title);
		sb.append("</a></li><br />");
	}

	public static ItemInfo[] load(Context ctx, int idx, int offset, int max) {
		if (Debug.DEBUG) {
			Log.d(TAG, "load ctx: " + ctx +" idx: " + idx + " offset: " + offset +" max: " + max);
		}
		ItemInfo[] list = null;
		switch (idx) {
		case LIST_ALL:
			list = loadAll(ctx, offset, max);
			break;
		case LIST_FAVES:
			list = loadFaves(ctx, offset, max);
			break;
		case LIST_MOST:
			list = loadMost(ctx, offset, max);
			break;
		case LIST_RECENT:
			list = loadRecent(ctx, offset, max);
			break;
		default:
		}
		if (Debug.DEBUG) {
			Log.d(TAG, "loaded: idx: " + idx + " : " + list);
		}
		return list;
	}

	public static String load(Context ctx, String s, int offset, int max) {
		final String base = SCHEME+"://localhost";
		return load(ctx, "Home", base, s, offset, max, true);
	}
	
	public static String load(Context ctx, String title, String base, String s, int offset, int max, boolean page) {
		int idx = match(s);
		//try loading max + 1
		ItemInfo[] items = load(ctx, idx, offset, max + 1);
		final String path = base + LIST[idx];
		String c = format(items, title, path, offset, max, page);
		return c;
	}

	private static void load(Cursor c, ArrayList<ItemInfo> list, int offset, int max) {
		if (Debug.DEBUG) {
			Log.d(TAG, "load cursor: " + c);
		}
		if (c == null) {
			return;
		}
		try {
			if (!c.moveToFirst()) {
				return;
			}
			offset = Math.max(0, offset);
			if (!c.move(offset)) {
				return;
			}
			int colId = c.getColumnIndex(Browser.BookmarkColumns._ID);
			int colTitle = c.getColumnIndex(Browser.BookmarkColumns.TITLE);
			int colUrl = c.getColumnIndex(Browser.BookmarkColumns.URL);
			int colIcon = c.getColumnIndex(Browser.BookmarkColumns.FAVICON);
			int colDate = c.getColumnIndex(Browser.BookmarkColumns.DATE);
			//
			int count = 0;
			long key = System.currentTimeMillis();

			do {
				ItemInfo fi = new ItemInfo();

				String id = c.getString(colId);
				fi.id = (id);

				String u = c.getString(colUrl);
				fi.url = (u);

				String t = c.getString(colTitle);
				if (t != null && t.length() > MAX_TEXT_LEN) {
					t = t.substring(0, MAX_TEXT_LEN);
				}
				fi.title = (t == null ? u : t);
				fi.date = c.getLong(colDate);
				byte[] data = c.getBlob(colIcon);
				if (data != null) {
					fi.icon = BitmapFactory.decodeByteArray(data, 0,
							data.length);
				} else {
					fi.icon = (null);
				}
				if (Debug.DEBUG) {
					Log.d(TAG, "title: " + t + " url: " + u);
				}

				key++;
				fi.sortkey = key + "";
				list.add(fi);
				count++;
				if (count > max) {
					break;
				}
			} while (c.moveToNext());
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			c.close();
		}
	}

	private static ItemInfo[] loadAll(Context ctx, int offset, int max) {
		ArrayList<ItemInfo> list = new ArrayList<ItemInfo>();
		//
		ContentResolver cr = ctx.getContentResolver();
		String by = Browser.BookmarkColumns.TITLE + " ASC";
		Cursor c = cr.query(Browser.BOOKMARKS_URI, BOOKMARK_PROJ, null, null,
				by);
		load(c, list, offset, max);
		return list.toArray(new ItemInfo[0]);
	}

	private static ItemInfo[] loadFaves(Context ctx, int offset, int max) {
		ArrayList<ItemInfo> list = new ArrayList<ItemInfo>();
		//
		ContentResolver cr = ctx.getContentResolver();
		String by = Browser.BookmarkColumns.TITLE + " ASC";
		Cursor c = cr.query(Browser.BOOKMARKS_URI, BOOKMARK_PROJ,
				"bookmark = 1", null, by);
		load(c, list, offset, max);
		return list.toArray(new ItemInfo[0]);
	}

	private static ItemInfo[] loadMost(Context ctx, int offset, int max) {
		ArrayList<ItemInfo> list = new ArrayList<ItemInfo>();
		//
		String sel = Browser.BookmarkColumns.VISITS + " != 0";
		String by = Browser.BookmarkColumns.VISITS + " DESC";
		ContentResolver cr = ctx.getContentResolver();
		Cursor c = cr
				.query(Browser.BOOKMARKS_URI, BOOKMARK_PROJ, sel, null, by);
		load(c, list, offset, max);
		return list.toArray(new ItemInfo[0]);
	}

	private static ItemInfo[] loadRecent(Context ctx, int offset, int max) {
		ArrayList<ItemInfo> list = new ArrayList<ItemInfo>();
		//
		String by = Browser.BookmarkColumns.DATE + " DESC";
		ContentResolver cr = ctx.getContentResolver();
		Cursor c = cr.query(Browser.BOOKMARKS_URI, BOOKMARK_PROJ, null, null,
				by);
		load(c, list, offset, max);
		return list.toArray(new ItemInfo[0]);
	}

	private static int match(String s) {
		String[] fl = LIST;
		int len = fl.length;
		for (int i = 0; i < len; i++) {
			if (fl[i].equals(s)) {
				return i;
			}
		}
		return -1;
	}

	public static void open(Context ctx, String title, String url) {
		try {
			Intent i = new Intent(Intent.ACTION_VIEW);
			i.setDataAndType(Uri.parse(url), "text/html");
			//
			Bundle b = new Bundle();
			b.putBoolean("new_window", true);
			i.putExtras(b);
			//
			Intent ci = Intent.createChooser(i, title);
			ci.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
			ctx.startActivity(ci);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private Bookmarks() {
	}
}
